import { Form, message } from 'ant-design-vue'
import type { CheckEvent } from 'ant-design-vue/es/tree/Tree'
import { type Ref, nextTick, onMounted, ref, watch } from 'vue'

import { materialApi } from '@/apis'
import type { VideoItem } from '@/apis/materialTypes'
import type { ProVideoProps, ProVideoRef } from '@/components'
import { useDialog } from '@/hooks'

import type { VideoForm } from '../types'

type Params = {
  videoData: Ref<VideoItem[]>
  handleGetVideoList: PromiseFunc
  handleGetGroupList: PromiseFunc
  handleGetVideoLimit: PromiseFunc
}

const { useForm } = Form

export function useVideo({
  videoData,
  handleGetVideoList,
  handleGetGroupList,
  handleGetVideoLimit
}: Params) {
  const videoListHeight = ref<Nullable<number>>(null)
  const selectedAll = ref(false)
  const indeterminate = ref(false)
  const selectedVideo = ref({})
  const selectedVideoIds = ref(new Set<number>())
  const showMove = ref(false)
  const showEditVideo = ref(false)
  const showPlayVideo = ref(false)
  const editVideoLoading = ref(false)
  const editVideoFormModel = ref({
    name: '',
    channel: undefined,
    cover: '',
    description: '',
    groupId: 2,
    size: undefined,
    suffix: '',
    videoUrl: ''
  } as Partial<VideoForm>)
  const editVideoFormRules = ref({
    name: [{ required: true, message: '请输入' }],
    channel: [{ required: true, message: '请选择' }],
    videoUrl: [{ required: true, message: '请上传' }],
    cover: [{ required: true, message: '请上传' }]
  } as FormRules)
  const videoRef = ref({} as ProVideoRef)
  const videoConfig = ref({
    options: {
      width: '100%',
      autoplay: true
    }
  } as ProVideoProps)
  const moveGroupLoading = ref(false)
  const moveGroupId = ref(undefined)
  const channelOptions = ref([
    { label: '所有渠道', value: 0 },
    { label: '翻牌', value: 1 }
  ] as OptionItem[])

  const editVideoFormRef = useForm(editVideoFormModel, editVideoFormRules)

  const { showConfirm } = useDialog()

  /** 全选 */
  function handleSelectAllChange(value: any, videoList: VideoItem[]) {
    const e = value.target as CheckEvent

    if (e.checked) {
      selectedVideoIds.value = new Set(videoList.map(v => v.id))
    } else {
      selectedVideoIds.value.clear()
    }

    indeterminate.value = false
  }

  /** 批量删除 */
  async function handleBatchDeleteVideo() {
    if (selectedVideoIds.value.size === 0) {
      message.warn('请选择至少1条记录')
      return
    }

    showConfirm({
      content: '确认删除视频？',
      onOk: async () => {
        try {
          await materialApi.batchDeleteVideo({
            ids: Array.from(selectedVideoIds.value)
          })

          handleGetVideoList()
          handleGetVideoLimit()
          handleGetGroupList()
        } catch (error) {}
      }
    })
  }

  /** 显示移动弹窗 */
  function handleShowMove() {
    if (selectedVideoIds.value.size === 0) {
      message.warn('请选择至少1条记录')
      return
    }

    showMove.value = true
  }

  /** 关闭移动弹窗 */
  function handleCloseMove() {
    moveGroupId.value = undefined
    showMove.value = false
    moveGroupLoading.value = false
  }

  /** 移动 */
  async function move() {
    try {
      moveGroupLoading.value = true

      await materialApi.batchMoveVideoGroup({
        groupId: moveGroupId.value,
        ids: Array.from(selectedVideoIds.value)
      })

      handleCloseMove()
      handleGetGroupList()
    } finally {
      moveGroupLoading.value = false
    }
  }

  /** 选择视频 */
  function handleSelectVideo(value: any, item: VideoItem) {
    const e = value.target as CheckEvent

    e.checked
      ? selectedVideoIds.value.add(item.id)
      : selectedVideoIds.value.delete(item.id)
  }

  /** 显示编辑视频弹窗 */
  function handleShowEditVideo(item: VideoItem) {
    showEditVideo.value = true

    nextTick(async () => {
      const data = await materialApi.getVideoDetail(item.id)
      Object.assign(editVideoFormModel.value, data)
    })
  }

  /** 关闭编辑视频弹窗 */
  function handleCloseEditVideo() {
    editVideoFormRef.resetFields()
    showEditVideo.value = false
    editVideoLoading.value = false
  }

  /** 编辑视频 */
  function editVideo() {
    editVideoFormRef
      .validate()
      .then(async () => {
        try {
          editVideoLoading.value = true

          await materialApi.updateVideo(editVideoFormModel.value)
          handleCloseEditVideo()
          handleGetVideoList()
        } finally {
          editVideoLoading.value = false
        }
      })
      .catch(() => {})
  }

  /** 删除视频 */
  function handleDeleteVideo(item: VideoItem) {
    showConfirm({
      content: '确认删除？',
      onOk: async () => {
        try {
          await materialApi.batchDeleteVideo({
            ids: [item.id]
          })

          handleGetVideoList()
          handleGetVideoLimit()
          handleGetGroupList()
        } catch {}
      }
    })
  }

  /** 显示播放视频 */
  function handleShowPlayVideo(item: VideoItem) {
    videoConfig.value.options!.url = item.videoUrl

    showPlayVideo.value = true
  }

  /** 关闭播放视频 */
  function handleClosePlayVideo() {
    showPlayVideo.value = false
  }

  /** 获取视频大小 */
  function getVideoSize(size: number) {
    return (size / 1024 / 1024).toFixed(3) + 'MB'
  }

  watch(
    selectedVideoIds,
    val => {
      indeterminate.value = !!val.size && val.size < videoData.value.length
      selectedAll.value = val.size === videoData.value.length
    },
    {
      deep: true
    }
  )

  onMounted(() => {
    const app = document.querySelector('#app')
    videoListHeight.value = app!.clientHeight - 400
  })

  return {
    videoListHeight,
    videoConfig,
    videoRef,
    selectedAll,
    indeterminate,
    selectedVideo,
    selectedVideoIds,
    showMove,
    showEditVideo,
    showPlayVideo,
    editVideoLoading,
    editVideoFormRef,
    editVideoFormModel,
    moveGroupLoading,
    channelOptions,
    moveGroupId,
    handleSelectAllChange,
    handleBatchDeleteVideo,
    handleShowMove,
    handleCloseMove,
    move,
    handleSelectVideo,
    handleShowEditVideo,
    handleCloseEditVideo,
    editVideo,
    handleDeleteVideo,
    handleShowPlayVideo,
    handleClosePlayVideo,
    getVideoSize
  }
}
